using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
using twimilar.DomainModel;

namespace twimilar.Services
{
	public class UsersRepository : IUsersRepositry
	{
		private readonly List<User> _users = new List<User>();

		#region IUsersRepositry Members

		public void SynchUsers(List<XElement> elements)
		{
			foreach (XElement element in elements)
			{
				string screenname =
					element.Elements().Where(x => x.Name.LocalName == "author").Elements().Where(x => x.Name.LocalName == "uri").First()
						.Value.ReplaceUriWithAt();
				string status = element.Elements().Where(x => x.Name.LocalName == "title").First().Value;
				var user = new User(screenname, status);

				if (_users.Where(x => x.TwitterUser.ScreenName == screenname).ToList().Count == 0)
					_users.Add(user);
				else
				{
					_users.Where(x => x.TwitterUser.ScreenName == screenname).First().AddTweet(status);
				}
			}
		}

		public ReadOnlyCollection<User> Users
		{
			get { return new ReadOnlyCollection<User>(_users); }
		}

		public List<KeyValuePair<User, int>> Top10Users(Account account)
		{
			var scores = new Dictionary<User, int>();

			List<User> usersWithWords = _users;
			//_users.Where(x => UserNotFriend(x, account)).ToList();
			foreach (User userWithWords in usersWithWords)
			{
				if (!scores.Keys.Contains(userWithWords))
					scores[userWithWords] = 0;

				foreach (string key in userWithWords.Words.Keys)
				{
					if (account.Words.Keys.Contains(key))
						scores[userWithWords] += userWithWords.Words[key];
				}
			}

			return scores.GetTop(10);
		}

		public List<KeyValuePair<User, int>> TopUsersMoreThan1(Account account)
		{
			var scores = new Dictionary<User, int>();

			List<User> usersWithWords = _users.Where(x => UserNotAccount(x, account)).ToList();
			//_users.Where(x => UserNotFriend(x, account)).ToList();
			foreach (User userWithWords in usersWithWords)
			{
				if (!scores.Keys.Contains(userWithWords))
					scores[userWithWords] = 0;

				foreach (string key in userWithWords.Words.Keys)
				{
					if (account.Words.Keys.Contains(key))
						scores[userWithWords] += userWithWords.Words[key];
				}
			}

			return scores.Where(x => x.Value > 1).OrderByDescending(x => x.Value).ToList();
		}

		private bool UserNotAccount(User user, Account account)
		{
			return !(user.TwitterUser.ScreenName == account.TwitterUser.ScreenName);
		}

		#endregion

		//private static bool UserNotFriend(User user, Account account)
		//{
		//  foreach (User friend in account.Friends)
		//  {
		//    if (friend.TwitterUser.ScreenName == user.TwitterUser.ScreenName
		//        || friend.TwitterUser.ScreenName == account.TwitterUser.ScreenName)
		//      return false;
		//  }
		//  return true;
		//}
	}
}